<template>
  <el-form label-width="150px" ref="formRef" :model="skuInfo" :rules="rules">
    <el-form-item label="SPU名称">
      <span>{{ spu.spuName }}</span>
    </el-form-item>
    <el-form-item label="SKU名称" prop="skuName">
      <el-input placeholder="SKU名称" v-model="skuInfo.skuName"></el-input>
    </el-form-item>
    <el-form-item label="价格(元)" prop="price">
      <el-input
        placeholder="价格"
        type="number"
        v-model="skuInfo.price"
      ></el-input>
    </el-form-item>
    <el-form-item label="重量(千克)" prop="weight">
      <el-input
        placeholder="重量"
        type="number"
        v-model="skuInfo.weight"
      ></el-input>
    </el-form-item>
    <el-form-item label="规格描述" prop="skuDesc">
      <el-input
        placeholder="规格描述"
        type="textarea"
        v-model="skuInfo.skuDesc"
      ></el-input>
    </el-form-item>
    <el-form-item label="平台属性" prop="skuAttrValueList">
      <el-form inline>
        <el-form-item
          :label="attr.attrName"
          v-for="attr in attrList"
          :key="attr.id"
        >
          <el-select
            v-model="attr.valueId"
            @change="formRef?.clearValidate(['skuAttrValueList'])"
          >
            <el-option
              :label="value.valueName"
              :value="value.id!"
              v-for="value in attr.attrValueList"
              :key="value.id"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </el-form-item>

    <el-form-item label="销售属性" prop="skuSaleAttrValueList">
      <el-form inline>
        <el-form-item
          :label="attr.saleAttrName"
          v-for="attr in spuSaleAttrList"
          :key="attr.id"
        >
          <el-select
            v-model="attr.valueId"
            @change="formRef?.clearValidate(['skuSaleAttrValueList'])"
          >
            <el-option
              :label="value.saleAttrValueName"
              :value="value.id!"
              v-for="value in attr.spuSaleAttrValueList"
              :key="value.id"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </el-form-item>

    <el-form-item label="图片列表" prop="skuImageList">
      <el-table :data="spuImageList" @selection-change="selectImageList">
        <el-table-column type="selection"></el-table-column>
        <el-table-column label="图片">
          <template v-slot="{ row }">
            <el-image
              :src="row.imgUrl"
              style="width: 100px; height: 100px"
            ></el-image>
          </template>
        </el-table-column>
        <el-table-column label="名称" prop="imgName"></el-table-column>
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-tag v-if="row.imgUrl === skuInfo.skuDefaultImg">默认</el-tag>
            <el-button
              v-else
              type="primary"
              :disabled="!selectedImageList.includes(row)"
              @click="setDefault(row)"
              >设置为默认</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item prop="skuDefaultImg"></el-form-item>
    <el-form-item>
      <el-button type="primary" @click="save">保存</el-button>
      <el-button @click="$emit('setShowStatus', ShowStatus.SPU_LIST)"
        >取消</el-button
      >
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
export default {
  name: 'SkuForm',
};
</script>

<script lang="ts" setup>
import { getAttrListApi } from '@/api/product/attr';
import type { AttrListModel } from '@/api/product/model/AttrModel';
import type {
  SkuModel,
  SkuAttrValueListModel,
  SkuSaleAttrValueListModel,
} from '@/api/product/model/skuModel';
import type {
  SpuImageListModel,
  SpuModel,
  SpuSaleAttrListModel,
  spuImageModel,
} from '@/api/product/model/spuModel';
import { saveSkuApi } from '@/api/product/sku';
import { getSpuImageListApi, getSpuSaleAttrListApi } from '@/api/product/spu';
import { useCategoryStore } from '@/stores/category';
import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
import { storeToRefs } from 'pinia';
import { onMounted, ref, reactive } from 'vue';
import { ShowStatus } from '../types';

// 声明定义自定义事件, 返回的是分发事件的函数
const emit = defineEmits<{
  (e: 'setShowStatus', value: ShowStatus): void;
}>();
// 声明接收props
const props = defineProps<{
  spu: SpuModel;
}>();

/* **请求保存 start** */
const save = async () => {
  await formRef.value?.validate();
  // alert('准备发添加sku的请求')
  // 1. 整理数据: skuInfo / selectedImageList / attrList / spuSaleAttrList

  /* 
  1) skuAttrValueList
		目标结构:
			{
        "attrId": "2",
        "valueId": "9"
      }
		现有结构:attrList
			{
				id => attrId
				valueId => valueId
			}
  */
  skuInfo.skuAttrValueList = attrList.value.reduce((pre, item) => {
    // 如果item中有valueId, 创建一个目标对象, 保存到pre
    if (item.valueId) {
      pre.push({
        attrId: item.id!,
        valueId: item.valueId!,
      });
    }
    return pre;
  }, [] as SkuAttrValueListModel); // 一定指定初始空数组的类型是SkuAttrValueListModel

  /* 
    2) skuSaleAttrValueList: [],
  	目标结构: 
			{
        "saleAttrValueId": 258
      }
		现有结构:spuSaleAttrList
			{
				valueId  => saleAttrValueId
			}
    */
  skuInfo.skuSaleAttrValueList = spuSaleAttrList.value.reduce((pre, item) => {
    // 如果item中有valueId, 创建一个目标对象, 保存到pre
    if (item.valueId) {
      pre.push({
        saleAttrValueId: item.valueId!,
      });
    }
    return pre;
  }, [] as SkuSaleAttrValueListModel);

  /* 
     3) skuImageList: [],
  	目标结构:
			{
        "imgName": "下载 (1).jpg",
        "imgUrl": "http://47.93.148.192:8080/xxx.jpg",
        "spuImgId": 337, // 当前Spu图片的id
        "isDefault": "1"   // 默认为"1", 非默认为"0"
      }
		现有结构: selectedImageList
			{
        "id": 333,
        "spuId": 26,
        "imgName": "rBHu8l6UcKyAfzDsAAAPN5YrVxw870.jpg",
        "imgUrl": "http://47.93.148.192:8080/xxx.jpg"
      }
    */
  skuInfo.skuImageList = selectedImageList.value.map((item) => ({
    imgName: item.imgName,
    imgUrl: item.imgUrl,
    spuImgId: item.id!, // 当前Spu图片的id
    isDefault: item.imgUrl === skuInfo.skuDefaultImg ? '1' : '0', // 默认为"1", 非默认为"0"
  }));

  // 2. 发送保存sku的请求, 提交skuInfo
  await saveSkuApi(skuInfo);

  // 3. 请求成功后: 提示 / 跳转到spu列表界面
  ElMessage.success('保存SKU成功啦!');
  emit('setShowStatus', ShowStatus.SPU_LIST);
};
/* **请求保存 end** */

/* **表单校验 start** */
const formRef = ref<FormInstance>();
const rules: FormRules = {
  skuName: [{ required: true, message: '名称是必须的' }],
  skuDesc: [{ required: true, message: '描述是必须的' }],
  price: [
    {
      validator: (rule, value, callback) => {
        // 要求价格大于0
        if (+value > 0) {
          callback(); // 校验通过
        } else {
          callback('价格必须大于0'); // 校验不通过, 并指定要显示的文本
        }
      },
    },
  ],
  weight: [
    {
      validator: (rule, value, callback) => {
        // 要求价格大于0
        if (+value > 0) {
          callback(); // 校验通过
        } else {
          callback('重量必须大于0'); // 校验不通过, 并指定要显示的文本
        }
      },
    },
  ],
  skuDefaultImg: [{ required: true, message: '默认图片是必须的' }],
  skuAttrValueList: [
    {
      validator: (rule, value, callback) => {
        // 判断attrList中是否至少有一个attr是有valueId的
        if (attrList.value.some((item) => item.valueId)) {
          callback();
        } else {
          callback('至少选择一个平台属性');
        }
      },
    },
  ],
  skuSaleAttrValueList: [
    {
      validator: (rule, value, callback) => {
        // 判断spuSaleAttrList中是否至少有一个attr是有valueId的
        if (spuSaleAttrList.value.some((item) => item.valueId)) {
          callback();
        } else {
          callback('至少选择一个销售属性');
        }
      },
    },
  ],
  skuImageList: [
    {
      validator: (rule, value, callback) => {
        // selectedImageList的长度大于0
        if (selectedImageList.value.length > 0) {
          callback(); // 校验通过
        } else {
          callback('至少选择一张图片'); // 校验不通过, 并指定要显示的文本
        }
      },
    },
  ],
};
/* **表单校验 end** */

/* 收集数据 start */
const skuInfo = reactive<SkuModel>({
  // props中读取
  category3Id: props.spu.category3Id!,
  // category3Id: category3Id.value!,
  spuId: props.spu.id!,
  tmId: props.spu.tmId!,
  // v-model收集
  skuName: '',
  skuDesc: '',
  price: 0,
  weight: 0,
  // 其它
  skuDefaultImg: '', // 默认图片url
  skuAttrValueList: [],
  skuSaleAttrValueList: [],
  skuImageList: [],
  isSale: 1,
});

// 所有选中的spu图片的数组
const selectedImageList = ref<SpuImageListModel>([]);

/* 
spu图片选中发生改变: 全选/全不选, 选中/不选中某个
values: 所有选中的spu图片的数组
*/
const selectImageList = (values: SpuImageListModel) => {
  selectedImageList.value = values;
};

const setDefault = (row: spuImageModel) => {
  // 保存默认图片
  skuInfo.skuDefaultImg = row.imgUrl;
  // 手动清除对应的校验错误
  formRef.value?.clearValidate(['skuDefaultImg']);
};

/* 收集数据 end */

/* 初始化请求获取数据 start */
// SPU图片列表
const spuImageList = ref<SpuImageListModel>([]);
// 平台属性列表
const attrList = ref<AttrListModel>([]);
// spu销售属性列表
const spuSaleAttrList = ref<SpuSaleAttrListModel>([]);

// 获取spu图片列表 spuImageList/5
// 获取平台属性列表  attrInfoList/2/13/61
// 获取spu销售属性列表: spuSaleAttrList/5
const { category1Id, category2Id, category3Id } = storeToRefs(
  useCategoryStore()
);
onMounted(async () => {
  // 只有当三个请求都成功后, 才去更新显示界面  => Promise.all(promises)
  const p1 = getSpuImageListApi(props.spu.id!);
  const p2 = getAttrListApi({
    category1Id: category1Id.value!,
    category2Id: category2Id.value!,
    category3Id: category3Id.value!,
  });
  const p3 = getSpuSaleAttrListApi(props.spu.id!);
  const results = await Promise.all([p1, p2, p3]);
  // 请求成功后更新数据
  spuImageList.value = results[0];
  attrList.value = results[1];
  spuSaleAttrList.value = results[2];
});

/* 初始化请求获取数据 end */
</script>

<style lang="scss" scoped></style>
